#ifndef SENDER_H
#define SENDER_H

#include "config.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

class Sender {
public:
	static constexpr double PI = 3.1415926897932384;

	Sender() {}
	Sender(const Config& conf):
		sigma(conf.sigma), port(conf.port), interval(conf.interval * 1000) {
		double theta = asin(sigma) / 2.0;
		cos_theta = cos(theta);
		sin_theta = sin(theta);
	}
	~Sender() {}

	void run();

private:
	//生成满足要求的浮点数
	void generateData() {
		//Box-Muller算法生成两个独立标准正态分布y1，y2
		double x1, x2, y1, y2;
		x1 = (double)rand() / (double)RAND_MAX;
		x2 = (double)rand() / (double)RAND_MAX;
		y1 = sqrt(-2 * log(x1)) * cos(2 * PI * x2);
		y2 = sqrt(-2 * log(x2)) * sin(2 * PI * x1);

		//通过两个独立标准正态分布生成相关系数为sigma的二维正态分布
		data[0] = cos_theta * y1 + sin_theta * y2;
		data[1] = sin_theta * y1 + cos_theta * y2;
	}

private:
	//含义同Config类中同名变量
	double sigma;
	int port;
	int interval;  //单位微秒，适应usleep函数
	const char* ip = "127.0.0.1";

	//生成data用到的系数，只与sigma有关
	double cos_theta, sin_theta;

private:
	//生成的浮点数
	double data[2];

};

void Sender::run() {

	struct sockaddr_in recver_addr;
	bzero(&recver_addr, sizeof(recver_addr));
	recver_addr.sin_family = AF_INET;
	inet_pton(AF_INET, ip, &recver_addr.sin_addr);
	recver_addr.sin_port = htons(port);

	int sockfd = socket(PF_INET, SOCK_STREAM, 0);
	assert(sockfd != -1);

	int ret = connect(sockfd, (struct sockaddr*)&recver_addr, 
		sizeof(recver_addr));
	assert(ret != -1);

	while (1) {
		generateData();
		ret = send(sockfd, data, sizeof(data), 0);
		if (ret == -1) {
			printf("Send data error.\n");
		}
		// printf("Send data: %.10f, %.10f\n", data[0], data[1]);
		usleep(interval);  //以微秒为单位，int可以表示11天多
	}
}

#endif